
<template>
  <div ref="rendererContainer" class="renderer-container"></div>
</template>

<script>
import * as THREE from 'three';
import Papa from 'papaparse';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

export default {
  name: 'SkeletonViewer',
  data() {
    return {
      skeletonData: [],
      currentFrameIndex: 0,
      lastTime: undefined // 新增属性，用于记录上一次渲染的时间
    };
  },
  mounted() {
    this.loadCSVData('/pose2.csv');
  },
  methods: {
    loadCSVData(filePath) {
      Papa.parse(filePath, {
        download: true,
        complete: (results) => {
          this.skeletonData = this.parseSkeletonData(results.data);
          this.initThreeJS();
        }
      });
    },
    parseSkeletonData(data) {
      return data.map(row => {
        const points = [];
        for (let i = 2; i < row.length; i += 4) {
          const x = parseFloat(row[i]);
          const y = parseFloat(row[i + 1]);
          const z = parseFloat(row[i + 2]);
          const visibility = parseFloat(row[i + 3]);

          if (!isNaN(x) && !isNaN(y) && !isNaN(z) ) {
              //points.push({ x, y, z });
              // 转换左手坐标系到右手坐标系
              points.push({ x: x, y: - y, z: -z });
          }
        }
        return points.length ? points : null;
      }).filter(points => points !== null);
    },
    initThreeJS() {
      const container = this.$refs.rendererContainer;
      const scene = new THREE.Scene();
      const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
      camera.position.set(20, 40, 90); // 调整相机位置
      
      // camera.position.set(20, 60, 70); // 调整相机位置
      camera.lookAt(new THREE.Vector3(0, 0, 0));

      const groundGeometry = new THREE.PlaneGeometry(100, 100);
      const groundMaterial = new THREE.MeshBasicMaterial({color: 0xcccccc, side: THREE.DoubleSide});
      const groundMesh = new THREE.Mesh(groundGeometry, groundMaterial);
      groundMesh.rotation.x = Math.PI / 2;
      scene.add(groundMesh);

      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(container.clientWidth, container.clientHeight);
      renderer.setClearColor(0xffffff);
      container.appendChild(renderer.domElement);

      // 添加轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true;
      controls.dampingFactor = 0.25;
      controls.enableZoom = true;

      // 添加坐标轴辅助器
      const axesHelper = new THREE.AxesHelper(50);
      scene.add(axesHelper);

      const ambientLight = new THREE.AmbientLight(0x404040);
      scene.add(ambientLight);

      // 添加平行光源
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
      directionalLight.position.set(1, 1, 1);
      scene.add(directionalLight);
      this.scene = scene;
      this.renderer = renderer;
      this.camera = camera;
      this.controls = controls;

  if (this.skeletonData.length > 0) {
    this.skeleton = this.createSkeleton(this.skeletonData[0]);
    if (this.skeleton) {
      scene.add(this.skeleton);
      this.animate();
    } else {
      console.error('Failed to create skeleton');
    }
  } else {
    console.error('No skeleton data available');
  }
    },
    createSkeleton(data) {
      const group = new THREE.Group();
      const jointMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
      const lineMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff });
      const xscaleFactor = 100;
      const yscaleFactor = 60;
      const zscaleFactor = 60;
      const points = data.map(point => new THREE.Vector3(point.x * xscaleFactor, point.y * yscaleFactor + 50, point.z * zscaleFactor));

      // 创建关节点
      points.forEach(point => {
        const jointGeometry = new THREE.SphereGeometry(0.5, 32, 32);
        const jointMesh = new THREE.Mesh(jointGeometry, jointMaterial);
        jointMesh.position.copy(point);
        group.add(jointMesh);
      });

      // 定义连接关系
      this.connections = [
      [0, 1], [1, 2], [2, 3], [0, 4], [4, 5], [5, 6],[3,7],[6,8], // 脸部
      [9, 10],  // 耳朵和嘴巴
      [11, 12],  // 颈部
      [11,13],[13, 15], [15, 17], [15, 19], [15, 21], [19,17],// 左臂和手指
      [11, 23], // 左肩到左臀
      [12, 14], [14, 16], [16, 22], [16, 18], [16, 20], [18, 20],// 右臂和手指
      [12, 24], // 右肩到右臀
      [23,24], //腰部
      [23, 25], [25, 27], [27, 29], [27, 31],[29,31],// 左腿和脚
      [24, 26], [26, 28], [28, 30], [28, 32],[30,32]  // 右腿和脚
      ];

      // 创建线条
      this.connections.forEach(([i, j]) => {
        if (points[i] && points[j]) {
          const geometry = new THREE.BufferGeometry().setFromPoints([points[i], points[j]]);
          const line = new THREE.Line(geometry, lineMaterial);
          group.add(line);
        }
      });

      return group;
    },
    animate(renderer, scene, camera, controls) {

    if (!this.renderer || !this.scene || !this.camera || !this.controls) return;

    const currentTime = performance.now();
    if (!this.lastTime) {
      this.lastTime = currentTime;
    }

    const deltaTime = currentTime - this.lastTime;
    if (deltaTime >= 1000 / 30) { // 每秒30帧，即每帧33.33毫秒
      this.lastTime = currentTime;

      this.controls.update();

      this.updateSkeletonPosition();

      this.renderer.render(this.scene, this.camera);
    }

    requestAnimationFrame(this.animate.bind(this));

    },

  updateSkeletonPosition() {
    if (this.skeletonData.length === 0) return;

    const currentFrameData = this.skeletonData[this.currentFrameIndex];
    const xscaleFactor = 100;
    const yscaleFactor = 60;
    const zscaleFactor = 20;

    currentFrameData.forEach((point, index) => {
      const jointMesh = this.skeleton.children[index];
      if (jointMesh instanceof THREE.Mesh) {
        jointMesh.position.set(
          point.x * xscaleFactor,
          point.y * yscaleFactor + 50,
          point.z * zscaleFactor
        );
      }
    });

  // 更新连接线
  let lineIndex = currentFrameData.length;
  this.skeleton.children.slice(currentFrameData.length).forEach(line => {
    if (line instanceof THREE.Line) {
      const [i, j] = this.connections[lineIndex - currentFrameData.length];
      const startPoint = currentFrameData[i];
      const endPoint = currentFrameData[j];
      if (startPoint && endPoint) {
        line.geometry.setFromPoints([
          new THREE.Vector3(startPoint.x * xscaleFactor, startPoint.y * yscaleFactor + 50, startPoint.z * zscaleFactor),
          new THREE.Vector3(endPoint.x * xscaleFactor, endPoint.y * yscaleFactor + 50, endPoint.z * zscaleFactor)
        ]);
        line.geometry.verticesNeedUpdate = true;
      }
      lineIndex++;
    }
  });

  // 更新帧索引
  this.currentFrameIndex = (this.currentFrameIndex + 1) % this.skeletonData.length;
  },
  }
  
};
</script>

<style scoped>
.renderer-container {
  width: 80%;
  height: 600px;
  border: 1px solid black;
}
</style>